﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using lopet.data;
using System.Threading;
using DiffisionWithDecomposition;

namespace Lopetvisualizer
{
    public partial class Form1 : Form
    {
        private bool _waitForIt;
        private Thread _t;
        private int _visualizationStepTime = 10;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            _t = new Thread(() => MainLoop());

            //ShannonsMutualInformation.MutualInformation(63, 87, 87, 61);

            _t.Start();

            //MainLoop();
        }

        public void MainLoop()
        {
            for (int i = 0; i < 10; i++)
            {
                var communication = new Communication();
                communication.SendOneBit(SimParameters.NumberOfMolecules, SimParameters.T_s);

                Simulation.Instance.EnqueueEvent(
                    new Event(Time.Instance.GetTimeAfterNanoSeconds(1), () => PrintXYProjection(communication)));

                while (Simulation.Instance.EndCondition == false)
                {
                    Simulation.Instance.DequeueEvent();
                }

                var mu = ShannonsMutualInformation.MutualInformation(communication.NumberOf0sSent, communication.NumberOf1sSent,
                    communication.NumberOf1sCorrectlyReceived, communication.NumberOf0sCorrectlyReceived);

                Console.WriteLine("threshold = " + SimParameters.DetectionThreshold + ", I = " + mu);

                SimParameters.DetectionThreshold += 2;
            }

        }

        private void PrintXYProjection(Communication communication)
        {
            PrintExtentions.PrintPoint(new lopet.data.Point(-20, -20, 0), this, 1000, Color.LightGray);

            PrintExtentions.PrintPoint(new lopet.data.Point(0, 0, 0), this, 3, Color.DarkRed);

            //this.label2.Text = Time.Instance.Now.ToString();

            foreach (var molecule in communication.Molecules)
            {
                molecule.Print(this);
            }

            communication.Cell.Print(this);

            Simulation.Instance.EnqueueEvent(
                    new Event(Time.Instance.GetTimeAfterNanoSeconds(_visualizationStepTime), () => PrintXYProjection(communication)));

            _waitForIt = true;

            while (_waitForIt)
            {
                Thread.Sleep(100);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _waitForIt = false;
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            if (_t != null)
            {
                _t.Abort();
            }

            base.OnFormClosed(e);
        }
    }
}
